/*
 * j4Win
 *  http://code.google.com/p/j4win/
 *
 * Copyright (C) 2006-2007 Felix Geyer, Moritz Laschinger
 *
 * This file is part of j4Win.
 *
 * j4Win is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * j4Win is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package j4win;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.Locale;

public class MainFrame extends Frame implements GUI, ActionListener, MouseMotionListener, MouseListener {
	private static final long serialVersionUID = 1L;
	
	// Game
	private Game game;
	private int winner = -1;
	
	//Menus
	private MenuBar menu;
	private Menu j4WinMenu;
	private Menu langMenu;
	private Menu aboutMenu;
	private MenuItem[] j4WinItems;
	private MenuItem[] langItems;
	private MenuItem[] aboutItems;
	
	// throw in Arrows
	private int throwArrow = 0;
	
	// Update
	private boolean arrowsChanged = false;
	private boolean scoreboardChanged = false;
	private boolean playgroundChanged = false;
	
	// Playground
	private Playground playground;
	private Scoreboard scoreboard;
	private final int xStart = 50;
	private final int yStart = 90;
	
	public final static Color backgroundColor = new Color(235, 235, 235);
	
	private BufferedImage bi;
	private Graphics bg;
	
	private Image arrow;
	private Image arrowdis;
	
	private PlayerListener listener;
	private Field field;
	
	private int playerTurn;
	
	public MainFrame() {
		ImageTracker.init(this);
		
		playground = new Playground(getToolkit(), this);
		scoreboard = new Scoreboard(getToolkit(), this);
		
		createMenu();
		setLayout(null);
		
		setResizable(false);
		setSize(700, 450);
		
		arrow = getToolkit().getImage( getClass().getClassLoader().getResource("gfx/arrow.png") ); //$NON-NLS-1$
		arrowdis = getToolkit().getImage( getClass().getClassLoader().getResource("gfx/arrowdis.png") ); //$NON-NLS-1$
		ImageTracker.addImage(arrow);
		ImageTracker.addImage(arrowdis);
		
		bi = new BufferedImage(700, 450, BufferedImage.TYPE_INT_ARGB);
		bg = bi.getGraphics();
		bg.setColor(backgroundColor);
		bg.fillRect(0, 0, bi.getWidth(), bi.getHeight());
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		addMouseMotionListener(this);
		addMouseListener(this);
		
		ImageTracker.waitForImages();
		arrowsChanged = true;
		scoreboardChanged = true;
		playgroundChanged = true;
		playground.genCells();
		repaint();
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == j4WinItems[0]) {
			NewGame dlg = new NewGame(this);
			dlg.setVisible(true);
			if (dlg.isOk()) {
				winner = -1;
				game = dlg.getGame(this);
				game.start();
			}
		}
		else if (e.getSource() == j4WinItems[1]) {
			System.exit(0);
		}
		else if (e.getSource() == langItems[0]) {
			Messages.setLocale(new Locale("en", "US"));
			retranslate();
		}
		else if (e.getSource() == langItems[1]) {
			Messages.setLocale(new Locale("de", "DE"));
			retranslate();
		}
		else if (e.getSource() == langItems[2]) {
			Messages.setLocale(new Locale("en", "1337"));
			retranslate();
		}
		else if (e.getSource() == aboutItems[0]) {
			About aboutDlg = new About(this);
			aboutDlg.setVisible(true);
		}
	}
	
	private void retranslate() {
		j4WinItems[0].setLabel(Messages.getString("MainFrame.new")); //$NON-NLS-1$
		j4WinItems[1].setLabel(Messages.getString("MainFrame.exit")); //$NON-NLS-1$
		langMenu.setLabel(Messages.getString("MainFrame.lang")); //$NON-NLS-1$
		aboutMenu.setLabel(Messages.getString("MainFrame.about")); //$NON-NLS-1$
		aboutItems[0].setLabel(Messages.getString("MainFrame.about")+" j4win"); //$NON-NLS-1$
		
		scoreboardChanged = true;
		playgroundChanged = true;
		
		repaint();
	}
	
	private void createMenu() {
		menu = new MenuBar();

		// J4Win
		j4WinMenu = new Menu("j4Win");; //$NON-NLS-1$
		
		j4WinItems = new MenuItem[2];
		j4WinItems[0] = new MenuItem(Messages.getString("MainFrame.new")); //$NON-NLS-1$
		j4WinItems[1] = new MenuItem(Messages.getString("MainFrame.exit")); //$NON-NLS-1$
		for (int i=0; i<j4WinItems.length; ++i)
			j4WinItems[i].addActionListener(this);
		
		j4WinMenu.add(j4WinItems[0]);
		j4WinMenu.addSeparator();
		j4WinMenu.add(j4WinItems[1]);
		
		menu.add(j4WinMenu);
		
		// Language
		langMenu  = new Menu(Messages.getString("MainFrame.lang")); //$NON-NLS-1$
		
		langItems = new MenuItem[3];
		langItems[0] = new MenuItem("English"); //$NON-NLS-1$
		langItems[0].addActionListener(this);
		langItems[1] = new MenuItem("Deutsch"); //$NON-NLS-1$
		langItems[1].addActionListener(this);
		langItems[2] = new MenuItem("1337 English"); //$NON-NLS-1$
		langItems[2].addActionListener(this);
		
		langMenu.add(langItems[0]);
		langMenu.add(langItems[1]);
		langMenu.add(langItems[2]);
		
		menu.add(langMenu);

		// About
		aboutMenu = new Menu(Messages.getString("MainFrame.about")); //$NON-NLS-1$
		
		aboutItems = new MenuItem[1];
		aboutItems[0] = new MenuItem(Messages.getString("MainFrame.about")+" j4win"); //$NON-NLS-1$
		aboutItems[0].addActionListener(this);
		
		aboutMenu.add(aboutItems[0]);
		
		menu.add(aboutMenu);
		
		
		setMenuBar(menu);
	}
	
	@Override
	public void paint(Graphics g) {
		draw(g);
	}
	
	@Override
	public void update(Graphics g) {
		draw(g);
	}
	
	private void draw(Graphics g) {
		if (arrowsChanged) {
			for (int i = 1; i < Field.WIDTH+1; ++i) {
				if (i == throwArrow && listener!=null && !field.isColFull(i-1)) {
					bg.drawImage(arrow, xStart+13+(throwArrow-1)*Playground.FIELDWIDTH, yStart, this);
				}
				else {
					bg.drawImage(arrowdis, xStart+13+(i-1)*Playground.FIELDWIDTH, yStart, this);
				}
			}
			arrowsChanged = false;
		}
		
		if (scoreboardChanged) {
			bg.drawImage(
				scoreboard.drawScoreboard(field, playerTurn, winner),
				xStart + 20 + Playground.FIELDWIDTH * Field.WIDTH,
				yStart+20,
				this
			);
			
			scoreboardChanged = false;
		}
		
		if (playgroundChanged) {
			bg.drawImage(playground.drawImage(winner), xStart, yStart+22, this);
			playgroundChanged = false;
		}
		
		g.drawImage(bi, 0, 0, this);
	}
	
	public void playerMoved(Field field, int col) {
		this.field = field;
		playground.setField(field.clone(), col);
		playgroundChanged = true;
		scoreboardChanged = true;
		repaint();
	}

	public void requestMove(int player, PlayerListener l) {
		listener = l;
	}

	public void playerWon(int player) {
		winner = player;
		playgroundChanged = true;
		scoreboardChanged = true;
		repaint();
	}

	public void tie() {
		winner = 3;
		playgroundChanged = true;
		scoreboardChanged = true;
		repaint();
	}

	public void turnChanged(int player) {
		playerTurn = player;
		scoreboardChanged = true;
		repaint();
	}
	
	public void mouseMoved(MouseEvent event) {
		if (event.getX() >= xStart && event.getX() <= xStart+Playground.FIELDWIDTH*Field.WIDTH && 
				event.getY() <= yStart+22 && event.getY() >= yStart) {
			if (throwInArrowChanged(event.getX())) {
				arrowsChanged = true;
				repaint();
			}
		}
		else {
			if (throwArrow != 0) {
				throwArrow = 0;
				arrowsChanged = true;
				repaint();
			}
		}
	}
	
	public void mouseClicked(MouseEvent e) {
		if (listener==null) return;
		if (e.getX() >= xStart && e.getX() <= xStart+Playground.FIELDWIDTH*Field.WIDTH && 
				e.getY() <= yStart+22 && e.getY() >= yStart) {
			for (int i = 0; i < Field.WIDTH; ++i) {
				if (xStart+(i)*Playground.FIELDWIDTH < e.getX() &&
						xStart+(i+1)*Playground.FIELDWIDTH > e.getX() &&
						!field.isColFull(i)
				) {
					PlayerListener l = listener;
					listener = null;
					l.move(i);
				}
			}
		}
	}
	
	private boolean throwInArrowChanged(int x) {
		for (int i = 1; i < Field.WIDTH+1; i++) {
			if (xStart+(i-1)*Playground.FIELDWIDTH < x &&  xStart+(i)*Playground.FIELDWIDTH > x) {
				if (throwArrow != i) {
					throwArrow = i;
					return true;
				}
				else {
					return false;
				}
			}
		}
		return false;
	}
	
	public void mouseDragged(MouseEvent arg0) {
	}

	public void mouseEntered(MouseEvent arg0) {
	}

	public void mouseExited(MouseEvent arg0) {
	}

	public void mousePressed(MouseEvent arg0) {
	}

	public void mouseReleased(MouseEvent arg0) {
	} 
}
